<template>
	<div class="wind-calendar-dialog">
		<w-cell
			v-if="cellType==='cell'"
			:title="cellLabel"
			:value="cellText"
			:disabled="disabled"
			:required="required"
			isLink
			@on-click="showModal"
		></w-cell>
		<div v-else class="wind-calendar-dialog__cell" @click="showModal">
			<span class="cell-text">{{cellText}}</span>
			<w-icon v-if="!disabled" type="select-arrow" class="select-arrow-icon"></w-icon>
		</div>
		<a-modal
			v-model:visible="visible"
			:title="title"
			:bodyStyle="{
				width: '45vw',
				height: '35vw',
				'padding': '1vw 1vw 2vw 1vw'
			}"
			centered
			width="45vw"
			class="wind-calendar-dialog__modal"
		>
			<div class="wind-calendar-dialog__calendar">
				<a-calendar
					v-model:value="calendarDate"
					:fullscreen="false"
					mode="month"
					value-format="YYYY-MM-DD"
					:validRange="validRange"
					:disabledDate="customDisableDateComputed"
					class="wind-calendar-dialog__calendar-date"
					@select="onPanelChange"
				>
				</a-calendar>
				<a-time-picker
					v-model:value="calendarTime"
					value-format="HH:mm"
					format="HH:mm"
					:disabledTime="disabledTime"
					:allowClear="false"
					inputReadOnly
					class="wind-calendar-dialog__calendar-time"
					@select="onTimeChange"
				/>
			</div>
			<template #footer>
				<a-button key="submit" type="primary" class="confirm-btn" @click="handleOk">确定</a-button>
			</template>
		</a-modal>
	</div>
</template>
<script lang="ts">
/**
 * CalendarDialog by shang 2022/9/21
 * @desc 日历
 *
 * @param {value}  [str]
 * @param {title} [str] - 标题
 * @param {cellType}  [String] - 单元格类型
 * @param {cellLabel}  [String] - 单元格label
 * @param {cellLabel}  [String] - 单元格label
 * @param {disabled}  [Boolean] - 是否禁用
 * @param {required}  [Boolean] - 是否必填
 * @param {enabledDate}  [Object] - 可选日期范围（startTime, endTime）
 *
 * @event {on-change} 切换日期时间后触发
 */
import { computed, defineComponent, ref } from 'vue'
import type { Dayjs } from 'dayjs'
import dayjs from 'dayjs'
export default defineComponent({
	name: 'w-calendar-dialog',
	props: {
		value: String,
		title: {
			type: String,
			default: '选择选项'
		},
		cellType: String,
		cellLabel: {
			type: String,
			default: ''
		},
		disabled: Boolean,
		required: Boolean,
		disabledDate: dayjs,
		customDisableDate: Boolean,
		enabledDate: {
			type: Object
		}
	},
	setup (props, { emit }) {
		const visible = ref<boolean>(false)
		const customDisableDateComputed = (current: Dayjs) => {
			if (props.customDisableDate) {
				return current && current > dayjs().endOf('day')
			} else {
				return false
			}
		}
		const showModal = () => {
			if (props.disabled) {
				return
			}
			initDateTime()
			initEnableTime()
			visible.value = true
		}
		const handleOk = () => {
			emtiDate()
			visible.value = false
		}
		const calendarDate = ref<Dayjs>()
		const calendarTime = ref<Dayjs>()
		let dateString = ''
		let timeString = ''
		const initDateTime = () => {
			let dateList = []
			if (!props.value) {
				dateList = dayjs().format('YYYY-MM-DD HH:mm:ss').split(' ')
			} else {
				dateList = props.value?.split(' ')
			}
			const [date, time] = dateList as string[]
			calendarDate.value = dayjs(date, 'YYYY-MM-DD')
			calendarTime.value = dayjs(time, 'HH:mm')
			dateString = date
			timeString = calendarTime.value.format('HH:mm')
		}

		const startTime = ref<String>()
		const endTime = ref<String>()
		// 不可选小时范围
		const hours = ref<Array<number>>()
		// 不可选分钟范围
		const minutes = ref<Array<number>>()
		const sameDay = ref<Boolean>()
		// 日历可选范围
		const validRange = ref<Array<Dayjs>>()

		const initEnableTime = () => {
			if (props.enabledDate) {
				startTime.value = props.enabledDate.startTime
				endTime.value = props.enabledDate.endTime
				if (startTime.value && !endTime.value) {
					validRange.value = [dayjs(startTime.value as string).subtract(1, 'day'), dayjs(startTime.value as string).add(10, 'year')]
				} else if (!startTime.value && endTime.value) {
					validRange.value = [dayjs(endTime.value as string).subtract(10, 'year'), dayjs(endTime.value as string).subtract(1, 'day')]
				} else {
					validRange.value = [dayjs(startTime.value as string).subtract(1, 'day'), dayjs(endTime.value as string).add(1, 'day')]
				}
				initDisableTime()
			}
		}

		// 不可选时间范围
		const disabledTime = computed(() => {
			return () => {
				return {
					disabledHours: () => hours.value,
					disabledMinutes: () => minutes.value
				}
			}
		})

		const initDisableTime = () => {
			// 开始日期是哪一天 （0-31）
			const day = dayjs(startTime.value as string)
			// 开始日期的小时数
			const hour = dayjs(startTime.value as string)
			// 如果是同一天，则只能选择开始日期之后的小时数
			if (day.isSame(dayjs(dateString), 'day')) {
				sameDay.value = true
				hours.value = range(0, dayjs(startTime.value as string).hour())
				if (hour.hour() === dayjs(timeString, 'HH:mm').hour()) {
					minutes.value = range(0, dayjs(startTime.value as string).minute())
				} else {
					minutes.value = []
				}
			} else if (day.isBefore(dayjs(dateString), 'day')) {
				sameDay.value = false
				hours.value = []
				minutes.value = []
			}
		}

		const onPanelChange = (value: string) => {
			// 开始日期是哪一天 （0-31）
			const day = dayjs(startTime.value as string)
			// 如果是同一天，则只能选择开始日期之后的小时数
			if (day.isSame(dayjs(value), 'day')) {
				sameDay.value = true
				hours.value = range(0, dayjs(startTime.value as string).hour())
				minutes.value = range(0, dayjs(startTime.value as string).minute())
			} else if (day.isBefore(dayjs(value), 'day')) {
				sameDay.value = false
				hours.value = []
				minutes.value = []
			}
			dateString = value
		}

		const onTimeChange = (value: string) => {
			// 开始日期的小时数
			const hour = dayjs(startTime.value as string)
			// 如果是同一天，则只能选择开始日期之后的小时数
			if (sameDay.value && hour.hour() === dayjs(value, 'HH:mm').hour()) {
				minutes.value = range(0, dayjs(startTime.value as string).minute())
			} else {
				minutes.value = []
			}
			timeString = dayjs(value).format('HH:mm')
		}

		// 获取范围
		const range = (start: number, end: number) => {
			const result = []
			for (let i = start; i < end; i++) {
				result.push(i)
			}
			return result
		}

		const emtiDate = () => {
			const dateValue = `${dateString} ${timeString}:00`
			emit('update:value', dateValue)
			emit('change', dateValue)
		}
		const cellText = computed(() => {
			if (!props.value) {
				return ''
			}
			const dateList = props.value?.split(' ')
			const [date, time] = dateList as string[]
			return `${date} ${dayjs(time, 'HH:mm').format('HH:mm')}`
		})
		return {
			visible,
			showModal,
			handleOk,
			calendarDate,
			calendarTime,
			disabledTime,
			onPanelChange,
			onTimeChange,
			cellText,
			validRange,
			customDisableDateComputed
		}
	}
})
</script>
<style lang="scss" scoped>
@import "$assets/stylus/varsty";
.wind-calendar-dialog {
    &__cell {
        display: flex;
        align-items: center;
        padding-right: 10px;
        padding-left: 15px;
        width: 280px;
        height: 36px;
        border: 1px solid #cccccc;
        border-radius: 20px;
        line-height: 36px;
        box-sizing: border-box;
        .cell-text {
            flex: 1;
            overflow:hidden;
            text-overflow : ellipsis;
            white-space:nowrap;
        }
        .select-arrow-icon {
            width: 10px;
            height: 10px;
        }
    }
}
.wind-calendar-dialog__modal {
    .wind-calendar-dialog__calendar {
        position:relative;
        &-date {
            :deep(.ant-picker-calendar-mode-switch) {
                width: 100px;
                label {
                    display:none;
                }
            }
        }
        &-time {
            position: absolute;
            top: 12px;
            right: 7px;
            width: 100px;
            height: 24px;
        }
    }
    .confirm-btn {
        width: 100%;
    }
}
</style>
